// Copyright (c) MatrixFramework. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Matrix.ServiceCommunication.Services;

/// <summary>
/// 服务发现提供者接口
/// </summary>
public interface IServiceDiscoveryProvider
{
    /// <summary>
    /// 获取服务地址
    /// </summary>
    /// <param name="serviceName">服务名称</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>服务地址</returns>
    Task<Uri> GetServiceAddressAsync(string serviceName, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取服务所有可用地址
    /// </summary>
    /// <param name="serviceName">服务名称</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>服务地址列表</returns>
    Task<IReadOnlyList<Uri>> GetServiceAddressesAsync(string serviceName, CancellationToken cancellationToken = default);

    /// <summary>
    /// 注册服务
    /// </summary>
    /// <param name="serviceRegistration">服务注册信息</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>注册结果</returns>
    Task RegisterServiceAsync(ServiceRegistration serviceRegistration, CancellationToken cancellationToken = default);

    /// <summary>
    /// 注销服务
    /// </summary>
    /// <param name="serviceName">服务名称</param>
    /// <param name="serviceId">服务ID</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>注销结果</returns>
    Task UnregisterServiceAsync(string serviceName, string serviceId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取所有已注册的服务
    /// </summary>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>服务列表</returns>
    Task<IReadOnlyList<ServiceInfo>> GetServicesAsync(CancellationToken cancellationToken = default);
}

/// <summary>
/// 服务注册信息
/// </summary>
public class ServiceRegistration
{
    /// <summary>
    /// 服务名称
    /// </summary>
    public string ServiceName { get; set; } = string.Empty;

    /// <summary>
    /// 服务ID
    /// </summary>
    public string ServiceId { get; set; } = string.Empty;

    /// <summary>
    /// 服务地址
    /// </summary>
    public Uri Address { get; set; } = null!;

    /// <summary>
    /// 服务端口
    /// </summary>
    public int Port { get; set; }

    /// <summary>
    /// 服务元数据
    /// </summary>
    public Dictionary<string, string> Metadata { get; set; } = new();

    /// <summary>
    /// 健康检查地址
    /// </summary>
    public string? HealthCheckUrl { get; set; }

    /// <summary>
    /// 标签
    /// </summary>
    public List<string> Tags { get; set; } = new();

    /// <summary>
    /// 权重
    /// </summary>
    public int Weight { get; set; } = 1;

    /// <summary>
    /// 是否启用
    /// </summary>
    public bool Enabled { get; set; } = true;
}

/// <summary>
/// 服务信息
/// </summary>
public class ServiceInfo
{
    /// <summary>
    /// 服务名称
    /// </summary>
    public string ServiceName { get; set; } = string.Empty;

    /// <summary>
    /// 服务实例列表
    /// </summary>
    public List<ServiceInstance> Instances { get; set; } = new();
}

/// <summary>
/// 服务实例
/// </summary>
public class ServiceInstance
{
    /// <summary>
    /// 服务ID
    /// </summary>
    public string ServiceId { get; set; } = string.Empty;

    /// <summary>
    /// 服务地址
    /// </summary>
    public Uri Address { get; set; } = null!;

    /// <summary>
    /// 服务端口
    /// </summary>
    public int Port { get; set; }

    /// <summary>
    /// 服务元数据
    /// </summary>
    public Dictionary<string, string> Metadata { get; set; } = new();

    /// <summary>
    /// 健康检查地址
    /// </summary>
    public string? HealthCheckUrl { get; set; }

    /// <summary>
    /// 标签
    /// </summary>
    public List<string> Tags { get; set; } = new();

    /// <summary>
    /// 权重
    /// </summary>
    public int Weight { get; set; } = 1;

    /// <summary>
    /// 是否启用
    /// </summary>
    public bool Enabled { get; set; } = true;

    /// <summary>
    /// 是否健康
    /// </summary>
    public bool Healthy { get; set; } = true;

    /// <summary>
    /// 注册时间
    /// </summary>
    public DateTime RegisteredAt { get; set; } = DateTime.UtcNow;

    /// <summary>
    /// 最后心跳时间
    /// </summary>
    public DateTime LastHeartbeat { get; set; } = DateTime.UtcNow;
}